<script>
let id = 0;
export default {
  props: {
    // 布局 值为 h (横向) 或者 v (纵向) 默认为 h
    layout: {
      type: [String],
      default: "h",
    },
    // 显示的数量 如为5，那么就会显示5项
    sliderNum: {
      type: [Number],
      default: 1,
    },
    autoPlay: {
      type: [Boolean],
      default: false,
      require: false,
    },
    autoPlayTime: {
      type: [Number],
      default: 100,
    },
    // 间隙
    gap: {
      type: [Number],
      default: 0,
    },
    // 数据源
    datasource: {},
    // 滚动速度
    speed: {
      type: [Number],
      default: 10,
    },
    moveNum: {
      type: [Number],
      default: 1,
    },
  },
  render() {
    let slotList = [];
    let allIndex = 1
    for (let data of this.datasource) {
      let slot = this.$scopedSlots.default({ item: data , index: allIndex });
      allIndex++;
      slotList.push(slot);
    }

    //复制列表
    if (this.sliderNum <= this.datasource.length) {
      let index = 0;
      for (let data of this.datasource) {
        if(index == this.datasource.length - 1) allIndex = 0
        let slot = this.$scopedSlots.default({ item: data , index: allIndex });
        allIndex++;
        index == this.datasource.length - 1
          ? slotList.unshift(slot)
          : slotList.push(slot);
        index++;
      }
    }

    let swiperDOM = (
      <div class="swiper-comp-container" id={'swiper-comp-container'+id}>
        <div class="swiper-comp-wrapper" id={'swiper-comp-wrapper'+id}>
          {slotList}
        </div>
      </div>
    );
    return swiperDOM;
  },
  data() {
    return {
      normalStep: 0,
      length: 0,
      currentTranslate: 0,
      currentIndex: 1,
      isReady: false,

      // 动画参数
      targetLength: 0, // 平移所需要的距离
      dir: 1, // 左为-1  右为1
    };
  },
  beforeCreate(){
    id++
  },
  mounted() {
    this.init()
    window.onresize = ()=>{
      clearTimeout(this.resizeTimer)
      this.resizeTimer = setTimeout(()=>{
        this.refresh()
      },200)
    }
  },
  methods: {
    init() {
      if(!this.p) {
        this.c = document.querySelector('#swiper-comp-container'+id)
        this.p = document.querySelector('#swiper-comp-wrapper'+id)
        this.p.addEventListener("mouseover", this.stopTimer);
        this.p.addEventListener("mouseleave", this.startTimer);
        this.getContainerLength();
      }
    },
    refresh() {
      this.init()
      this.isReady = false;
      // 如果数据源长度小于滚动长度，不开启滚动--start
      if (this.sliderNum >= this.datasource.length) {
        let sliderList = this.p.children;
        let containerLength = this.getContainerLength();
        this.setSliderStyle(sliderList, containerLength);
        return;
      }
      // 如果数据源长度小于滚动长度，不开启滚动--end

      this.currentTranslate = -this.getStepLength();
      this.currentIndex = 1;
      this.translate(this.currentTranslate);

      this.length = this.datasource.length;
      let sliderList = this.p.children;
      this.setSliderStyle(sliderList);

      this.isReady = true;

      this.startTimer();
    },
    // 设置每一项的样式
    setSliderStyle(sliderList) {
      let itemLength = this.getItemLength()
      for (let slider of sliderList) {
        let layout = this.layout == "h" ? "width" : "height";
        slider.style[layout] = itemLength + "px";
        slider.style["margin-right"] = this.gap + "px";
        slider.style["flex-shrink"] = 0;
      }
    },
    // 获取当前容器的长度，即可见区域的长度
    getContainerLength() {
      let rect = this.c.getBoundingClientRect()
      if (this.layout == "h") return rect.width;
      else return rect.height;
    },
    // 每一步移动的距离
    getStepLength() {
      let containerLength = this.getContainerLength();
      let stepLength =
        (containerLength - (this.sliderNum - 1) * this.gap) / this.sliderNum +
        this.gap;
      return stepLength;
    },
    // 每一项的长度
    getItemLength() {
      return this.getStepLength() - this.gap;
    },
    // 容器平移
    translate(length) {
      if (this.layout == "h") {
        this.p.style["transform"] = `translate3d(${length}px, 0px , 0px`;
      } else {
        this.p.style["transform"] = `translate3d(0px, ${length}px , 0px`;
      }
    },
    // 尾部节点交换到第一个位置
    endNodeExchange() {
      let first = this.p.children[0];
      let last = this.p.children[this.p.children.length - 1];
      this.p.insertBefore(last, first);
    },
    async swipeGo(dir) {
      if (this.isMoving) return;
      this.isMoving = true;
      this.targetLength = this.getStepLength();
      this.dir = dir;
      await this.animate();
    },
    animate() {
      return new Promise((resolve) => {
        this.animateStart(resolve);
      });
    },
    animateStart(cb) {
      this.currentIndex += this.dir;
      this.cb = cb;

      if (this.currentIndex == -1) {
        this.currentIndex = this.length - 1;
        this.currentTranslate = -1 * this.getStepLength() * this.length;
        this.translate(this.currentTranslate);
      }
      if (this.currentIndex == this.length + this.length - this.sliderNum + 1) {
        this.currentIndex = this.length - this.sliderNum;
        this.currentTranslate = this.currentIndex * -1 * this.getStepLength()
        this.translate(this.currentTranslate);

        // 以上操作只是进行相位变换， 所以必须要再自增一次才算是 move的这一次
        this.currentIndex ++ ;
      }

      this.animateMove();
    },
    animateMove() {
      let newTargetLength = this.targetLength - this.speed;
      if (newTargetLength <= 0) {
        this.currentTranslate -= this.dir * this.targetLength;
        this.targetLength = 0;
        this.isMoving = false;
        this.translate(this.currentTranslate);
        this.animateEnd();
      } else {
        this.currentTranslate -= this.dir * this.speed;
        this.targetLength -= 1 * this.speed;
        this.translate(this.currentTranslate);
        requestAnimationFrame(this.animateMove);
      }
    },
    animateEnd() {
      this.cb && this.cb();
    },
    async left() {
      this.stopTimer();
      for (let i of Array(this.moveNum)) {
        await this.swipeGo(-1);
      }
      this.startTimer();
    },
    async right() {
      this.stopTimer();
      for (let i of Array(this.moveNum)) {
        await this.swipeGo(1);
      }
      this.startTimer();
    },
    autoPlayProcessor() {
      if (this.mouseIn) return;
      clearTimeout(this.autoPlayTimer);
      this.autoPlayTimer = setTimeout(async () => {
        await this.right();
        this.autoPlayProcessor();
      }, this.autoPlayTime);
    },
    stopTimer(event) {
      if (!this.isReady) return;
      if (event) this.mouseIn = true;
      clearTimeout(this.autoPlayTimer);
    },
    startTimer(event) {
      if (!this.isReady) return;
      if (event) this.mouseIn = false;
      if (this.autoPlay) {
        this.autoPlayProcessor();
      }
    },
  },
  beforeDestroy() {
    clearTimeout(this.autoPlayTimer);
    window.onresize = null
  },
};
</script>

<style lang="less" scoped>
.swiper-comp-container {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.swiper-comp-wrapper {
  display: flex;
  width: 100%;
  height: 100%;
  transition-property: transform;
  will-change: transform;
  transition-duration: 0ms;
}
</style>